package com.fastloan.mgt.invest.service.impl;

import com.fastloan.common.BasicServiceImpl;
import com.fastloan.mgt.invest.dao.InvestTempMapper;
import com.fastloan.mgt.invest.dao.InvestTempVarMapper;
import com.fastloan.mgt.invest.dao.InvestValueMapper;
import com.fastloan.mgt.invest.model.InvestCusTemp;
import com.fastloan.mgt.invest.model.InvestCustomer;
import com.fastloan.mgt.invest.model.InvestValue;
import com.fastloan.mgt.invest.model.vo.InvestTempVarVo;
import com.fastloan.mgt.invest.model.vo.WorldCusVo;
import com.fastloan.mgt.invest.model.vo.WorldFormVo;
import com.fastloan.mgt.invest.model.vo.WorldValueVo;
import com.fastloan.mgt.invest.service.InvestCusTempService;
import com.fastloan.mgt.invest.service.InvestCustomerService;
import com.fastloan.mgt.invest.service.InvestValueService;
import com.fastloan.mgt.invest.utils.DocUtil;
import com.fastloan.safe.mgt.org.model.CmuOrg;
import com.fastloan.safe.mgt.org.model.CmuOrgUser;
import com.fastloan.safe.mgt.org.service.CmuOrgService;
import com.fastloan.safe.mgt.org.service.CmuOrgUserService;
import com.fastloan.safe.mgt.sys.service.CmSysFileService;
import com.kawins.util.VerifyCodeUtil;
import com.kawins.util.file.ZipUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.zip.ZipOutputStream;

/**
 * @author rankai createTime 2017-08-2017/8/8 10:29
 */
@Service
public class InvestValueServiceImpl extends BasicServiceImpl<InvestValue> implements InvestValueService {

    @Autowired
    private InvestTempVarMapper investTempVarMapper;

    @Autowired
    private InvestCustomerService investCustomerService;

    @Autowired
    private InvestCusTempService investCusTempService;

    @Autowired
    private InvestValueMapper investValueMapper;

    @Autowired
    private InvestTempMapper investTempMapper;

    @Autowired
    private CmSysFileService sysFileService;

    @Autowired
    private CmuOrgUserService orgUserService;

    @Autowired
    private CmuOrgService orgService;

    @Override
    @Transactional
    public Map<String, Object> insertValue(HttpServletRequest request, InvestCustomer investCustomer,
                                           String managerId, String tempId, String typeId, String subjectId) {
        List<CmuOrgUser> select = orgUserService.select(new CmuOrgUser().setUserId(managerId));
        List<CmuOrg> cmuOrgs = orgService.selectTopOrgBySon(select.get(0).getOrgId(), false, true);
        log.debug("收到问卷,此问卷所在客户经理机构{},顶级机构{}", select.size(), cmuOrgs.size());
        investCustomer.setTopOrgId(cmuOrgs.get(0).getId());
        investCustomerService.insertSelective(investCustomer);
        InvestCusTemp investCusTemp = new InvestCusTemp();
        investCusTemp.setTempId(tempId);
        investCusTemp.setCustomerId(investCustomer.getId());
        investCusTemp.setUserId(managerId);
        investCusTemp.setTypeId(typeId);
        investCusTemp.setCreateTime(new Date());
        investCusTemp.setSubjectId(subjectId);
        InvestCusTemp investCusTempOne = new InvestCusTemp();
        Map<String, Object> map = new HashMap<>();
        while (true) {
            String code = VerifyCodeUtil.generateTextCode(VerifyCodeUtil.TYPE_NUM_ONLY, 6, null);
            int parseInt = Integer.parseInt(code);
            investCusTempOne.setCode("HB" + parseInt);
            if (investCusTempService.selectCount(investCusTempOne) == 0) {
                investCusTemp.setCode("HB" + parseInt);
                map.put("code", "HB" + code);
                break;
            }
        }
        investCusTempService.insertSelective(investCusTemp);
        List<InvestTempVarVo> investTempVarVos = investTempVarMapper.selectByTempId(tempId, typeId);
        List<InvestValue> list = new ArrayList<>();
        List<String> errorList = new ArrayList<>();
        for (int i = 0; i < investTempVarVos.size(); i++) {
            String parameter = request.getParameter(investTempVarVos.get(i).getId());
            if (investTempVarVos.get(i).getNotNull() == 1 && parameter == null) {
                errorList.add("题目'" + investTempVarVos.get(i).getCname() + "'不能为空");
                continue;
            } else if (errorList.size() > 0) {
                continue;
            }
            InvestValue investValue = new InvestValue();
            investValue.setCusTempId(investCusTemp.getId());
            investValue.setValue(parameter);
            investValue.setFormId(investTempVarVos.get(i).getId());
            list.add(investValue);
        }
        if (errorList.size() > 0) {
            map.remove("code");
            map.put("error", errorList);
            investCustomerService.deleteByPrimaryKey(investCustomer.getId());
            investCusTempService.deleteByPrimaryKey(investCusTemp.getId());
            return map;
        }
        investValueMapper.insertList(list);
        CmuOrgUser cmuOrgUser = new CmuOrgUser();
        cmuOrgUser.setUserId(managerId);
        cmuOrgUser = orgUserService.selectOne(cmuOrgUser);
        CmuOrg cmuOrg = orgService.selectByPrimaryKey(cmuOrgUser.getOrgId());
        if (cmuOrg != null && cmuOrg.getWeixinCode() != null) {
            map.put("erCode", sysFileService.selectByPrimaryKey(cmuOrg.getWeixinCode()));
        }
        return map;
    }

    @Override
    public void worldBySubject(String cusValueId, String subjectId, HttpServletRequest request, HttpServletResponse response) {
        List<String> cusValueIds = new ArrayList<>();
        if (cusValueId == null) {
            String customerName = request.getParameter("customerName");
            String startTime = request.getParameter("startTime");
            String endTime = request.getParameter("endTime");
            String idCard = request.getParameter("idCard");
            String managerName = request.getParameter("managerName");
            Map<String, Object> map = new HashMap<>();
            if (StringUtils.isNotBlank(customerName)) {
                map.put("customerName", customerName);
            }
            if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
                map.put("startTime", startTime);
                map.put("endTime", endTime);
            }
            if (StringUtils.isNotBlank(idCard)) {
                map.put("idCard", idCard);
            }
            if (StringUtils.isNotBlank(managerName)) {
                map.put("managerName", managerName);
            }
            if (map.size() > 0) {
                map.put("subjectId", subjectId);
                cusValueIds = investTempMapper.selectForWorld(map);
            }
        } else {
            cusValueIds.add(cusValueId);
        }

        List<WorldValueVo> worldTempVoList = investTempMapper.selectToWorldValueVo(cusValueIds, subjectId);
        if (worldTempVoList != null && worldTempVoList.size() > 0) {
            List<WorldCusVo> worldCusVos = createBean(worldTempVoList);
            batch(worldCusVos, response);
        }
    }

    @Override
    public WorldCusVo showCusValue(String cusValueId) {
        String subjectId = investCusTempService.selectByPrimaryKey(cusValueId).getSubjectId();
        List<String> list = new ArrayList<>();
        list.add(cusValueId);
        List<WorldValueVo> worldTempVoList = investTempMapper.selectToWorldValueVo(list, subjectId);
        if (worldTempVoList != null && worldTempVoList.size() > 0) {
            List<WorldCusVo> worldCusVos = createBean(worldTempVoList);
            return worldCusVos.size() > 0 ? worldCusVos.get(0) : null;
        }
        return null;
    }

    private List<WorldCusVo> createBean(List<WorldValueVo> worldTempVoList) {
        List<WorldCusVo> worldCusVoList = new ArrayList<>();
        for (WorldValueVo worldValueVo : worldTempVoList) {
            List<WorldCusVo> worldCusVos = investCustomerService.selectByTempId(worldValueVo.getTempId(), worldValueVo.getTempCusId());
            for (WorldCusVo worldCusVo : worldCusVos) {
                worldCusVo.setWorldValueVo(worldValueVo);
                List<WorldFormVo> worldFormVoList = investValueMapper
                        .selectToWorldFormVo(worldCusVo.getTempId(), worldCusVo.getTypeId(), worldCusVo.getCusTempId());
                worldCusVo.setWorldFormVoList(worldFormVoList);
            }
            worldCusVoList.addAll(worldCusVos);
        }
//        System.out.println(JSON.toJSON(worldCusVoList));
        return worldCusVoList;
    }

    private void batch(List<WorldCusVo> worldCusVos, HttpServletResponse response) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String realPath = request.getServletContext().getRealPath("/WEB-INF/static/temp/");
        String code = VerifyCodeUtil.generateTextCode(VerifyCodeUtil.TYPE_NUM_ONLY, 32, null);
        String finalPath = realPath + code;
        makeDirs(finalPath);
        DocUtil docUtil = new DocUtil();
        Map<String, Object> map = new HashMap<>();
        String filePath;
        for (WorldCusVo worldCusVo : worldCusVos) {
            map.put("worldCusVo", worldCusVo);
            filePath = finalPath + "/" + worldCusVo.getCustomerName() + "_" +
                    worldCusVo.getPhone() + "_" + VerifyCodeUtil.generateTextCode
                    (VerifyCodeUtil.TYPE_NUM_ONLY, 3, null);
            docUtil.createDoc(map, "doc", filePath + ".doc");
        }
        response.setContentType("APPLICATION/OCTET-STREAM");
        String zipName = VerifyCodeUtil.generateTextCode(VerifyCodeUtil.TYPE_NUM_ONLY, 6, null);
        response.setHeader("Content-Disposition", "attachment; filename=" + zipName + ".zip");
        ZipOutputStream out = null;
        try {
            out = new ZipOutputStream(response.getOutputStream());
            ZipUtils.doCompress(finalPath, out);
            response.flushBuffer();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            deleteDir(new File(finalPath));
        }
    }

    private boolean makeDirs(String filePath) {
        File folder = new File(filePath);
        return (folder.exists() && folder.isDirectory()) || folder.mkdirs();
    }

    private boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i = 0; i < children.length; i++) {
                boolean success = deleteDir(new File(dir, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        return dir.delete();
    }
}
